pytest testing

安装量: 73
排名: #10666

安装

npx skills add https://github.com/pluginagentmarketplace/custom-plugin-python --skill 'Pytest Testing'

Pytest Testing Overview Master software testing with pytest, Python's most popular testing framework. Learn test-driven development (TDD), write maintainable tests, and ensure code quality through comprehensive testing strategies. Learning Objectives Write unit, integration, and functional tests with pytest Use fixtures for test setup and teardown Mock external dependencies effectively Implement test-driven development (TDD) Measure and improve code coverage Integrate tests with CI/CD pipelines Core Topics 1. Pytest Basics Test discovery and naming conventions Assertions and comparison Test organization (files, classes, modules) Running tests (command-line options) Markers and test selection Parametrized tests Code Example:

test_calculator.py

import pytest def add ( a , b ) : return a + b def divide ( a , b ) : if b == 0 : raise ValueError ( "Cannot divide by zero" ) return a / b

Basic test

def test_add ( ) : assert add ( 2 , 3 ) == 5 assert add ( - 1 , 1 ) == 0 assert add ( 0 , 0 ) == 0

Test exceptions

def test_divide_by_zero ( ) : with pytest . raises ( ValueError , match = "Cannot divide by zero" ) : divide ( 10 , 0 )

Parametrized test

@pytest . mark . parametrize ( "a,b,expected" , [ ( 10 , 2 , 5 ) , ( 20 , 4 , 5 ) , ( 100 , 10 , 10 ) , ( - 10 , 2 , - 5 ) , ] ) def test_divide ( a , b , expected ) : assert divide ( a , b ) == expected

Test with marker

@pytest . mark . slow def test_complex_operation ( ) :

This test takes a long time

result

sum ( range ( 1000000 ) ) assert result == 499999500000 2. Fixtures & Test Setup Fixture scopes (function, class, module, session) Fixture dependencies Parametrized fixtures Built-in fixtures (tmpdir, capsys, monkeypatch) conftest.py for shared fixtures Code Example:

conftest.py

import pytest import tempfile from pathlib import Path @pytest . fixture def sample_data ( ) : """Provide sample data for tests""" return { 'users' : [ { 'id' : 1 , 'name' : 'Alice' , 'email' : 'alice@example.com' } , { 'id' : 2 , 'name' : 'Bob' , 'email' : 'bob@example.com' } , ] } @pytest . fixture def temp_file ( ) : """Create temporary file for testing""" with tempfile . NamedTemporaryFile ( mode = 'w' , delete = False ) as f : f . write ( "Test data" ) temp_path = f . name yield temp_path

Cleanup

Path ( temp_path ) . unlink ( ) @pytest . fixture ( scope = 'module' ) def database_connection ( ) : """Module-scoped database connection""" db = DatabaseConnection ( 'test.db' ) db . connect ( ) yield db db . close ( )

test_users.py

def test_user_count ( sample_data ) : assert len ( sample_data [ 'users' ] ) == 2 def test_user_names ( sample_data ) : names = [ user [ 'name' ] for user in sample_data [ 'users' ] ] assert 'Alice' in names assert 'Bob' in names def test_file_operations ( temp_file ) : content = Path ( temp_file ) . read_text ( ) assert content == "Test data" 3. Mocking & Test Doubles unittest.mock basics Mocking functions and methods Patching objects Mock assertions Side effects and return values Testing with external dependencies Code Example:

api_client.py

import requests class APIClient : def init ( self , base_url ) : self . base_url = base_url def get_user ( self , user_id ) : response = requests . get ( f" { self . base_url } /users/ { user_id } " ) response . raise_for_status ( ) return response . json ( ) def create_user ( self , user_data ) : response = requests . post ( f" { self . base_url } /users" , json = user_data ) response . raise_for_status ( ) return response . json ( )

test_api_client.py

from unittest . mock import Mock , patch import pytest @patch ( 'api_client.requests.get' ) def test_get_user ( mock_get ) :

Setup mock

mock_response

Mock ( ) mock_response . json . return_value = { 'id' : 1 , 'name' : 'Alice' } mock_response . raise_for_status . return_value = None mock_get . return_value = mock_response

Test

client

APIClient ( 'https://api.example.com' ) user = client . get_user ( 1 )

Assertions

assert user [ 'name' ] == 'Alice' mock_get . assert_called_once_with ( 'https://api.example.com/users/1' ) @patch ( 'api_client.requests.post' ) def test_create_user ( mock_post ) :

Setup mock

mock_response

Mock ( ) mock_response . json . return_value = { 'id' : 3 , 'name' : 'Charlie' } mock_post . return_value = mock_response

Test

client

APIClient ( 'https://api.example.com' ) user_data = { 'name' : 'Charlie' , 'email' : 'charlie@example.com' } result = client . create_user ( user_data )

Assertions

assert result [ 'id' ] == 3 mock_post . assert_called_once_with ( 'https://api.example.com/users' , json = user_data ) 4. Coverage & CI/CD Integration Measuring code coverage with pytest-cov Coverage reports (terminal, HTML, XML) Setting coverage thresholds GitHub Actions integration GitLab CI integration Pre-commit hooks Code Example:

pytest.ini

[ tool : pytest ] testpaths = tests python_files = test_ * . py python_classes = Test * python_functions = test_ * addopts = - - cov = myapp - - cov - report = html - - cov - report = term - missing - - cov - fail - under = 80 - v

.github/workflows/test.yml

name : Tests on : [ push , pull_request ] jobs : test : runs - on : ubuntu - latest steps : - uses : actions / checkout@v3 - name : Set up Python uses : actions / setup - python@v4 with : python - version : '3.11' - name : Install dependencies run : | pip install - r requirements . txt pip install pytest pytest - cov - name : Run tests run : | pytest - - cov = myapp - - cov - report = xml - name : Upload coverage uses : codecov / codecov - action@v3 with : file : . / coverage . xml

Command line usage

Run all tests

pytest

Run with coverage

pytest

- cov = myapp

Generate HTML coverage report

pytest

- cov = myapp - - cov - report = html

Run specific test file

pytest tests / test_api . py

Run tests with marker

pytest

m slow

Run tests with verbose output

pytest

v

Stop on first failure

pytest

x Hands-On Practice Project 1: Calculator TDD Build a calculator using test-driven development. Requirements: Write tests BEFORE implementation Basic operations (add, subtract, multiply, divide) Error handling (division by zero) Scientific operations (power, sqrt, log) Test coverage > 90% Key Skills: TDD workflow, parametrized tests, exception testing Project 2: API Testing Suite Create comprehensive test suite for a REST API. Requirements: Mock HTTP requests Test CRUD operations Error handling tests Authentication tests Integration tests CI/CD pipeline setup Key Skills: Mocking, fixtures, integration testing Project 3: Database Testing Test database operations with fixtures and transactions. Requirements: Setup test database fixture Test CRUD operations Transaction rollback Data validation Performance tests Coverage report Key Skills: Database fixtures, cleanup, performance testing Assessment Criteria Write clear, maintainable tests Use fixtures appropriately Mock external dependencies effectively Achieve >80% code coverage Follow TDD principles Integrate tests with CI/CD Write meaningful assertions Resources Official Documentation Pytest Docs - Official documentation pytest-cov - Coverage plugin unittest.mock - Mocking library Learning Platforms Test-Driven Development with Python - TDD book Python Testing with pytest - Brian Okken's book Real Python Testing - Tutorials Tools pytest-xdist - Parallel testing pytest-mock - Mocking helper Hypothesis - Property-based testing tox - Testing automation Next Steps After mastering pytest, explore: Property-based testing - Hypothesis library Performance testing - pytest-benchmark Mutation testing - mutmut Load testing - Locust, pytest-load

返回排行榜